package data.join.com.socket;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.util.Log;

import data.join.com.media.DeviceRegisterThread;
import data.join.com.utils.MyLog;

/**
 * Created by Administrator on 2017/11/13.
 */

public class OfflineAlarmConnect {

    private final String TAG = OfflineAlarmConnect.class.getSimpleName();

    private final static int WAKEUP_DELAY = 10 * 60 * 1000;

    private Context mContext;
    private BroadcastReceiver alarmReceiver;
    private PendingIntent pendingIntent;

    private volatile boolean hasStarted = false;

    private static OfflineAlarmConnect mInstance;

    public static synchronized OfflineAlarmConnect getInstance(Context context){
        if(mInstance == null){
            mInstance = new OfflineAlarmConnect(context);
        }
        return mInstance;
    }

    private OfflineAlarmConnect(Context context){
        mContext = context;
        this.alarmReceiver = new AlarmReceiver();
    }

    public void start() {
        String action = TAG;
        MyLog.D(TAG, "Register alarmreceiver to Service "+ action);
        mContext.registerReceiver(alarmReceiver, new IntentFilter(action));

        pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(action), PendingIntent.FLAG_UPDATE_CURRENT);

        schedule(WAKEUP_DELAY);
        hasStarted = true;
    }

    public void stop() {
        MyLog.D(TAG, "Unregister alarmreceiver");
        if(hasStarted){
            if(pendingIntent != null){
                // Cancel Alarm.
                AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Service.ALARM_SERVICE);
                alarmManager.cancel(pendingIntent);
            }

            hasStarted = false;
            try{
                mContext.unregisterReceiver(alarmReceiver);
            }catch(IllegalArgumentException e){
                //Ignore unregister errors.
            }
        }
    }

    private void schedule(long delayInMilliseconds) {
        long nextAlarmInMilliseconds = System.currentTimeMillis() + delayInMilliseconds;
        MyLog.D(TAG, "Schedule next alarm at " + nextAlarmInMilliseconds);
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Service.ALARM_SERVICE);

        if(Build.VERSION.SDK_INT >= 23){
            // In SDK 23 and above, dosing will prevent setExact, setExactAndAllowWhileIdle will force
            // the device to run this task whilst dosing.
            MyLog.D(TAG, "Alarm scheule using setExactAndAllowWhileIdle, next: " + delayInMilliseconds);
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextAlarmInMilliseconds,pendingIntent);
        } else if (Build.VERSION.SDK_INT >= 19) {
            MyLog.D(TAG, "Alarm scheule using setExact, delay: " + delayInMilliseconds);
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, nextAlarmInMilliseconds,pendingIntent);
        } else {
            alarmManager.set(AlarmManager.RTC_WAKEUP, nextAlarmInMilliseconds,pendingIntent);
        }
    }

    class AlarmReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            MyLog.D(TAG,"onReceive");

            DeviceRegisterThread.getInstance(mContext).wakeUp();

            if(DeviceRegisterThread.getInstance(mContext).isDevicesRegister()) {
                AliMqttClient.getInstance(mContext).connectServer();
            }

            schedule(WAKEUP_DELAY);
        }
    }
}
